package handler

import (
	"github.com/gin-gonic/gin"
	"go_shengshu_admin/enum"
	"go_shengshu_admin/model"
	"go_shengshu_admin/query"
	"go_shengshu_admin/resp"
	"go_shengshu_admin/service"
	"net/http"
)

type CategoryHandler struct {
	Srv service.CategorySrv
}

func (h *CategoryHandler) GetEntity(result []*model.CategoryResult) map[string]*resp.Category {
	var thirdCategory *resp.Category3
	for _, item := range result {
		thirdCategory = &resp.Category3{
			Id:         item.C3CategoryId,
			Key:        item.C3CategoryId,
			CategoryId: item.C3CategoryId,
			Name:       item.C3Name,
			Order:      item.C3Order,
			ParentId:   item.C3ParentId,
			IsDeleted:  item.IsDeleted,
		}
	}

	var secondCategory *resp.Category2
	for _, item := range result {
		secondCategory = &resp.Category2{
			CategoryId: item.C2CategoryId,
			Name:       item.C2Name,
			Order:      item.C2Order,
			ParentId:   item.C2ParentId,
			Children:   *thirdCategory,
		}
	}

	cmap := make(map[string]*resp.Category)
	for _, item := range result {
		firstCategory := &resp.Category{
			CategoryId: item.C1CategoryId,
			Name:       item.C1Name,
			Desc:       item.C1Desc,
			Order:      item.C1Order,
			ParentId:   item.C1ParentId,
			Children:   *secondCategory,
		}
		cmap[item.C1CategoryId] = firstCategory
	}

	return cmap
}

func (h *CategoryHandler) CategoryInfoHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	id := c.Param("id")
	if id == "" {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	result, err := h.Srv.Get(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	entity = resp.Entity{
		Code:      int(enum.OperateOk),
		Msg:       enum.OperateOk.String(),
		Data:      result,
		Total:     0,
		TotalPage: 0,
	}
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})

}

/**
 ** 针对后台，条形结构
 */
func (h *CategoryHandler) CategoryList4BackendHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	var q query.ListQuery
	if err := c.ShouldBindQuery(&q); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	list, err := h.Srv.List()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	total, err := h.Srv.GetTotal()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	totalPage := 0
	pageSize := q.PageSize

	if pageSize == 0 {
		pageSize = 5
	}
	if total != 0 {
		ret := int(total % pageSize)
		ret2 := int(total / pageSize)
		if ret == 0 {
			totalPage = ret2
		} else {
			totalPage = ret2 + 1
		}
	}

	for _, item := range list {
		item.Key = item.C3CategoryId
		item.Id = item.C3CategoryId
	}

	entity = resp.Entity{
		Code:      int(enum.OperateOk),
		Msg:       enum.OperateOk.String(),
		Data:      list,
		Total:     total,
		TotalPage: totalPage,
	}

	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})
}

/**
 * 树状结构
 */
func (h *CategoryHandler) CategoryListHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	var q query.ListQuery
	if err := c.ShouldBindQuery(&q); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	list, err := h.Srv.List()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	total, err := h.Srv.GetTotal()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	totalPage := 0
	pageSize := q.PageSize

	if pageSize == 0 {
		pageSize = 5
	}
	if total != 0 {
		ret := int(total % pageSize)
		ret2 := int(total / pageSize)
		if ret == 0 {
			totalPage = ret2
		} else {
			totalPage = ret2 + 1
		}
	}

	newList := h.GetEntity(list)

	entity = resp.Entity{
		Code:      int(enum.OperateOk),
		Msg:       enum.OperateOk.String(),
		Data:      newList,
		Total:     total,
		TotalPage: totalPage,
	}

	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})

}

func (h *CategoryHandler) AddCategoryHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	var category model.Category
	if err := c.ShouldBindJSON(&category); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	b, err := h.Srv.Add(category)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	if !b {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}

	entity = resp.Entity{
		Code:      int(enum.OperateOk),
		Msg:       enum.OperateOk.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})
}

func (h *CategoryHandler) EditCategoryHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	var category model.Category
	if err := c.ShouldBindJSON(&category); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	b, err := h.Srv.Edit(category)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	if !b {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = enum.OperateOk.String()
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})
}

func (h *CategoryHandler) DeleteCategoryHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 0,
	}
	id := c.Param("id")
	b, err := h.Srv.Delete(id)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	if !b {
		c.JSON(http.StatusOK, gin.H{
			"entity": entity,
		})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = enum.OperateOk.String()
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})
}
